package com.hellogood.yaohuo.client.bussiness.fanchang;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.hellogood.yaohuo.client.common.CommonMessages;
import com.hellogood.yaohuo.client.common.GoodsSearchWindow;
import com.hellogood.yaohuo.client.common.LoginUser;
import com.hellogood.yaohuo.client.common.Tools;
import com.hellogood.yaohuo.shared.entity.Org;
import com.hellogood.yaohuo.shared.entity.ThDetail;
import com.hellogood.yaohuo.shared.entity.ThForm;
import com.hellogood.yaohuo.shared.entity.Vendor;
import com.hellogood.yaohuo.shared.services.ColorService;
import com.hellogood.yaohuo.shared.services.CommonService;
import com.hellogood.yaohuo.shared.services.CupService;
import com.hellogood.yaohuo.shared.services.FanchangService;
import com.hellogood.yaohuo.shared.services.OrgService;
import com.hellogood.yaohuo.shared.services.VendorService;
import com.hellogood.yaohuo.shared.vo.BasicVo;
import com.hellogood.yaohuo.shared.vo.FanchangDetailVo;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.DateDisplayFormat;
import com.smartgwt.client.types.EnterKeyEditAction;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.RowEndEditAction;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.DateItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.form.validator.IsIntegerValidator;
import com.smartgwt.client.widgets.grid.HeaderSpan;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.EditorExitEvent;
import com.smartgwt.client.widgets.grid.events.EditorExitHandler;
import com.smartgwt.client.widgets.layout.Layout;
import com.smartgwt.client.widgets.layout.VLayout;

public class FormController {
	private Record[] data = null;

	private TextItem codeItem = null;
	private SelectItem vendorItem = null;
	private SelectItem orgItem = null;
	private DateItem dateItem = null;
	private TextItem zdUserItem = null;
	private TextItem remarkItem = null;

	private ListGrid listGrid = null;
	private DynamicForm form = null;
	private Layout layout = null;

	public FormController() {
		initData();
		initView();
	}

	private void initData() {
		data = new ListGridRecord[1];
		Record r = new ListGridRecord();
		data[0] = r;
		ColorService.Util.getInstance().getAllColorMap(new ColorAsyncCallback());
		CupService.Util.getInstance().getAllCupMap(new CupAsyncCallback());
	}

	private void initView() {
		codeItem = new TextItem("code", "单据号");
		codeItem.setCanEdit(false);
		codeItem.setValue("*");
		vendorItem = new SelectItem("vendor", "供应商");
		vendorItem.setCanEdit(false);
		vendorItem.setRequired(true);
		orgItem = new SelectItem("org", "门店");
		orgItem.setCanEdit(false);
		orgItem.setRequired(true);
		orgItem.addChangedHandler(new OrgChangedHandler());
		dateItem = new DateItem("date", "日期");
		dateItem.setDateFormatter(DateDisplayFormat.TOJAPANSHORTDATE);
		dateItem.setUseTextField(true);
		dateItem.setCanEdit(false);
		zdUserItem = new TextItem("zdUser", "制单人");
		zdUserItem.setCanEdit(false);
		remarkItem = new TextItem("reamrk", "备注");

		form = new DynamicForm();
		form.setSize("50%", "10%");
		form.setAlign(Alignment.CENTER);
		form.setNumCols(4);
		form.setFields(codeItem, vendorItem, orgItem, dateItem, zdUserItem, remarkItem);

		IsIntegerValidator isIntegerValidator = new IsIntegerValidator();

		ListGridField codeField = new ListGridField("pluCode", "编码");
		codeField.setWidth("7%");
		ListGridField barCodeField = new ListGridField("barCode", "条码");
		barCodeField.setWidth("10%");
		barCodeField.setCanEdit(false);
		ListGridField pmField = new ListGridField("pluName", "品名");
		pmField.setWidth("15%");
		pmField.setCanEdit(false);
		ListGridField deptField = new ListGridField("dept", "部门");
		deptField.setWidth("8%");
		deptField.setCanEdit(false);
		ListGridField typeField = new ListGridField("type", "品类");
		typeField.setWidth("8%");
		typeField.setCanEdit(false);
		ListGridField unitField = new ListGridField("unit", "单位");
		unitField.setWidth("5%");
		unitField.setCanEdit(false);
		ListGridField cupField = new ListGridField("cup", "杯级");
		cupField.setWidth("5%");
		ListGridField colorField = new ListGridField("color", "颜色");
		colorField.setWidth("5%");
		ListGridField size1Field = new ListGridField("size1", "S/58");
		size1Field.setWidth("5%");
		size1Field.setValidators(isIntegerValidator);
		size1Field.setAlign(Alignment.CENTER);
		size1Field.setType(ListGridFieldType.INTEGER);
		size1Field.setValidateOnChange(true);
		ListGridField size2Field = new ListGridField("size2", "M/64");
		size2Field.setWidth("5%");
		size2Field.setValidators(isIntegerValidator);
		size2Field.setAlign(Alignment.CENTER);
		size2Field.setType(ListGridFieldType.INTEGER);
		size2Field.setValidateOnChange(true);
		ListGridField size3Field = new ListGridField("size3", "L/70");
		size3Field.setWidth("5%");
		size3Field.setValidators(isIntegerValidator);
		size3Field.setAlign(Alignment.CENTER);
		size3Field.setType(ListGridFieldType.INTEGER);
		size3Field.setValidateOnChange(true);
		ListGridField size4Field = new ListGridField("size4", "XL/76");
		size4Field.setWidth("5%");
		size4Field.setValidators(isIntegerValidator);
		size4Field.setAlign(Alignment.CENTER);
		size4Field.setType(ListGridFieldType.INTEGER);
		size4Field.setValidateOnChange(true);
		ListGridField size5Field = new ListGridField("size5", "XXL/82");
		size5Field.setWidth("5%");
		size5Field.setValidators(isIntegerValidator);
		size5Field.setAlign(Alignment.CENTER);
		size5Field.setType(ListGridFieldType.INTEGER);
		size5Field.setValidateOnChange(true);
		ListGridField size6Field = new ListGridField("size6", "XXXL/88");
		size6Field.setWidth("5%");
		size6Field.setValidators(isIntegerValidator);
		size6Field.setAlign(Alignment.CENTER);
		size6Field.setType(ListGridFieldType.INTEGER);
		size6Field.setValidateOnChange(true);
		ListGridField sizeField = new ListGridField("size", "均码");
		sizeField.setWidth("5%");
		sizeField.setValidators(isIntegerValidator);
		sizeField.setType(ListGridFieldType.INTEGER);
		sizeField.setValidateOnChange(true);
		ListGridField jPriceField = new ListGridField("jPrice", "进价");
		jPriceField.setCanEdit(false);
		jPriceField.setWidth("7%");
		ListGridField priceField = new ListGridField("price", "售价");
		priceField.setWidth("7%");
		ListGridField amountField = new ListGridField("amount", "数量");
		amountField.setWidth("7%");
		amountField.setCanEdit(false);
		ListGridField costField = new ListGridField("cost", "进价金额");
		costField.setCanEdit(false);
		costField.setWidth("7%");
		ListGridField totalField = new ListGridField("total", "售价金额");
		totalField.setCanEdit(false);
		totalField.setWidth("7%");
		ListGridField remarkField = new ListGridField("remark", "备注");
		remarkField.setWidth("10%");
		ListGridField[] fields = new ListGridField[] { codeField, barCodeField, pmField, deptField, typeField, unitField, cupField, colorField, size1Field, size2Field, size3Field, size4Field,
				size5Field, size6Field, sizeField, jPriceField, priceField, amountField, costField, totalField, remarkField };
		listGrid = new ListGrid();
		listGrid.setFields(fields);
		listGrid.setHeaderHeight(40);
		listGrid.setSize("170%", "100%");
		listGrid.setDisabled(true);
		listGrid.setCanEdit(true);
		listGrid.setShowRowNumbers(true);
		listGrid.setHeaderSpans(new HeaderSpan("70", new String[] { "size1" }), new HeaderSpan("75", new String[] { "size2" }), new HeaderSpan("80", new String[] { "size3" }), new HeaderSpan("85",
				new String[] { "size4" }), new HeaderSpan("90", new String[] { "size5" }), new HeaderSpan("95", new String[] { "size6" }));

		listGrid.setEnterKeyEditAction(EnterKeyEditAction.NEXTCELL);
		listGrid.setListEndEditAction(RowEndEditAction.NEXT);
		listGrid.addEditorExitHandler(new OrgCodeEditorExitHandler());
		listGrid.setSelectOnEdit(true);

		VLayout gridLayout = new VLayout();
		gridLayout.setOverflow(Overflow.SCROLL);
		gridLayout.setSize("100%", "90%");
		gridLayout.addMember(listGrid);

		Label titleLabel = new Label();
		titleLabel.setWidth("100%");
		titleLabel.setHeight(40);
		titleLabel.setAlign(Alignment.CENTER);
		titleLabel.setContents("<H2>商品返厂单</H2>");

		layout = new VLayout();
		layout.setSize("100%", "100%");
		layout.setMembers(titleLabel, form, gridLayout);
	}

	public ListGrid getListGrid() {
		return listGrid;
	}

	public Canvas getCanvas() {
		return layout;
	}

	public void initForm() {
		orgItem.setCanEdit(true);
		vendorItem.setCanEdit(true);
		Date date = new Date();
		dateItem.setValue(date);
		zdUserItem.setValue(LoginUser.getInstance().getCurrentUser().getStaffCode() + "-" + LoginUser.getInstance().getCurrentUser().getStaffName());
		String staffCode = LoginUser.getInstance().getCurrentUser().getStaffCode();
		OrgService.Util.getInstance().getOrgListByStaffCode(staffCode, new OrgListAsynCallback());
		VendorService.Util.getInstance().getAllVendorList(new VendorListAsynCallback());
		listGrid.setData(data);
	}

	public void cancelForm() {
		orgItem.setCanEdit(false);
		vendorItem.setCanEdit(false);
		dateItem.setValue("");
		zdUserItem.setValue("");
		vendorItem.setValueMap(new LinkedHashMap<String, String>());
		orgItem.setValueMap(new LinkedHashMap<String, String>());
		orgItem.setValue("");
		remarkItem.setValue("");
		listGrid.setData(new Record[0]);
		listGrid.setDisabled(true);
	}

	public void deleteForm() {

		Object billNo = orgItem.getValue();
		if (billNo != null) {
			FanchangService.Util.getInstance().deleteForm(billNo.toString(), new AsyncCallback<String>() {

				@Override
				public void onFailure(Throwable caught) {
					SC.say(caught.getMessage());
				}

				@Override
				public void onSuccess(String result) {
					if (!result.equals("")) {
						SC.say(result);
					} else {
						SC.say(CommonMessages.DeleteSuccess);
					}
				}
			});
		}

	}

	public void updateForm(ThForm form) {
		codeItem.setValue(form.getThBillNo());
		orgItem.setValue(form.getOrgCode() + "-" + form.getOrgName());
		dateItem.setValue(form.getThDate());
		zdUserItem.setValue(form.getStaffCode() + "-" + form.getStaffName());
		remarkItem.setValue(form.getRemark());
		List<FanchangDetailVo> list = form.getVoList();
		Record[] rds = new Record[list.size()];
		for (int i = 0; i < list.size(); i++) {
			FanchangDetailVo vo = list.get(i);
			Record r = new Record();
			r.setAttribute("pluCode", vo.getPluCode());
			r.setAttribute("barCode", vo.getBarCode());
			r.setAttribute("pluName", vo.getPluName());
			r.setAttribute("dept", vo.getDepCode());
			r.setAttribute("type", vo.getClsCode());
			r.setAttribute("unit", "");
			r.setAttribute("cup", vo.getBra());
			r.setAttribute("color", vo.getColor());
			r.setAttribute("size1", vo.getSize1());
			r.setAttribute("size2", vo.getSize2());
			r.setAttribute("size3", vo.getSize3());
			r.setAttribute("size4", vo.getSize4());
			r.setAttribute("size5", vo.getSize5());
			r.setAttribute("size6", vo.getSize6());
			r.setAttribute("size", vo.getSize());
			r.setAttribute("amount", vo.getCounts());
			r.setAttribute("remark", vo.getRemark());
			rds[i] = r;
		}
		listGrid.setData(rds);
	}

	public void bankForm() {
		Object code = codeItem.getValue();
		if (code != null) {
			List<String> list = new ArrayList<String>();
			list.add(code.toString());
			FanchangService.Util.getInstance().bankForm(list, new AsyncCallback<String>() {

				@Override
				public void onSuccess(String result) {
					if (!result.equals("")) {
						SC.say(result);
					} else {
						SC.say(CommonMessages.BankSuccess);
					}
				}

				@Override
				public void onFailure(Throwable caught) {
					SC.say(caught.getMessage());
				}
			});
		}
	}

	public void saveForm() {
		boolean isModify = false;
		Object billNo = codeItem.getValue();
		if (billNo != null && !billNo.equals("*")) {
			isModify = true;
		}

		if (!isModify) {
			String orgCode = orgItem.getValue().toString().split("-")[0];
			FanchangService.Util.getInstance().getLastFcBillNo(orgCode, new SaveAsyncCallback(billNo, isModify));
		} else {
			save(billNo.toString(), isModify);
		}
	}

	private class SaveAsyncCallback implements AsyncCallback<String> {
		Object billNo = null;
		boolean isModify = false;

		public SaveAsyncCallback(Object billNo, boolean isModify) {
			this.billNo = billNo;
			this.isModify = isModify;
		}

		@Override
		public void onFailure(Throwable caught) {
			SC.say(caught.getMessage());
		}

		@Override
		public void onSuccess(String result) {
			save(billNo.toString(), isModify);
		}
	}

	private String save(String billNo, boolean isModify) {
		ThForm form = new ThForm();
		form.setThBillNo(billNo);
		form.setThDate(dateItem.getValue().toString());
		form.setRemark(remarkItem.getValue().toString());
		form.setRzDate("");
		form.setStaffCode(zdUserItem.getValue().toString().split("-")[0]);
		form.setTimeMark(Tools.getTodayFormattedDate());
		form.setStaffName(zdUserItem.getValue().toString().split("-")[1]);

		List<ThDetail> list = new ArrayList<ThDetail>();
		Record[] rds = listGrid.getRecords();
		if (rds.length > 0) {
			int totalFormCount = 0;
			for (int i = 0; i < rds.length; i++) {
				ThDetail d = new ThDetail();
				d.setThBillNo(billNo);
				d.setOrgCode(form.getOrgCode());
				d.setRzDate("");
				d.setTotal(new BigDecimal(0));
				d.setNetCost(new BigDecimal(0));
				d.setCost(new BigDecimal(0));
				d.setjPrice(new BigDecimal(0));
				// d.setNetPrice(new BigDecimal(0));
				d.setPrice(new BigDecimal(0));
				d.setTimeMark(Tools.getTodayFormattedDate());

				Record r = rds[i];
				d.setPluCode(r.getAttribute("pluCode"));
				d.setBarCode(r.getAttribute("barCode"));
				d.setPluName(r.getAttribute("pluName"));
				d.setDepCode(r.getAttribute("dept").split("-")[0]);
				d.setBarCode(r.getAttribute("dept").split("-")[1]);
				d.setBra(r.getAttribute("cup"));
				d.setColor(r.getAttribute("color"));
				d.setRemark(r.getAttribute("remark"));
				if (r.getAttribute("size1") != null) {
					ThDetail yhd = d;
					yhd.setSize("1");
					int count = Integer.valueOf(r.getAttribute("size1"));
					totalFormCount += count;
					yhd.setCounts(count);
					list.add(yhd);
				}
				if (r.getAttribute("size2") != null) {
					ThDetail yhd = d;
					yhd.setSize("2");
					int count = Integer.valueOf(r.getAttribute("size2"));
					totalFormCount += count;
					yhd.setCounts(count);
					list.add(yhd);
				}
				if (r.getAttribute("size3") != null) {
					ThDetail yhd = d;
					yhd.setSize("3");
					int count = Integer.valueOf(r.getAttribute("size3"));
					totalFormCount += count;
					yhd.setCounts(count);
					list.add(yhd);
				}
				if (r.getAttribute("size4") != null) {
					ThDetail yhd = d;
					yhd.setSize("4");
					int count = Integer.valueOf(r.getAttribute("size4"));
					totalFormCount += count;
					yhd.setCounts(count);
					list.add(yhd);
				}
				if (r.getAttribute("size5") != null) {
					ThDetail yhd = d;
					yhd.setSize("5");
					int count = Integer.valueOf(r.getAttribute("size5"));
					totalFormCount += count;
					yhd.setCounts(count);
					list.add(yhd);
				}
				if (r.getAttribute("size6") != null) {
					ThDetail yhd = d;
					yhd.setSize("6");
					int count = Integer.valueOf(r.getAttribute("size6"));
					totalFormCount += count;
					yhd.setCounts(count);
					list.add(yhd);
				}
				if (r.getAttribute("size7") != null) {
					ThDetail yhd = d;
					yhd.setSize("7");
					int count = Integer.valueOf(r.getAttribute("size7"));
					totalFormCount += count;
					yhd.setCounts(count);
					list.add(yhd);
				}
				r.getAttribute("amount");
			}
			form.setCounts(totalFormCount);
			form.setCost(new BigDecimal(0));
			form.setNetCost(new BigDecimal(0));
			form.setTotal(new BigDecimal(0));
			form.setList(list);

			FanchangService.Util.getInstance().saveForm(form, isModify, new SaveResultAsyncCallback(form.getThBillNo()));
		}

		return "";
	}

	private class SaveResultAsyncCallback implements AsyncCallback<String> {
		private String billNo = null;

		public SaveResultAsyncCallback(String billNo) {
			this.billNo = billNo;
		}

		@Override
		public void onFailure(Throwable caught) {
			SC.say(caught.getMessage());
		}

		@Override
		public void onSuccess(String result) {
			if (!result.equals("")) {
				SC.say(result);
			} else {
				SC.say(CommonMessages.SaveSuccess);
				codeItem.setValue(billNo);
				orgItem.setCanEdit(false);
				remarkItem.setCanEdit(true);
				listGrid.setDisabled(true);
			}

		}
	}

	private class OrgListAsynCallback implements AsyncCallback<List<Org>> {

		@Override
		public void onFailure(Throwable caught) {
			SC.say(caught.getMessage());
		}

		@Override
		public void onSuccess(List<Org> result) {
			LinkedHashMap<String, String> orgMap = new LinkedHashMap<String, String>();
			if (result != null) {
				for (int i = 0; i < result.size(); i++) {
					Org o = result.get(i);
					orgMap.put(o.getOrgCode(), o.getOrgName());
					if (i == 0) {
						orgItem.setValue(o.getOrgCode());
					}
				}
				orgItem.setValueMap(orgMap);
			}
		}

	}

	private class VendorListAsynCallback implements AsyncCallback<List<Vendor>> {

		@Override
		public void onFailure(Throwable caught) {
			SC.say(caught.getMessage());
		}

		@Override
		public void onSuccess(List<Vendor> result) {
			LinkedHashMap<String, String> vendorMap = new LinkedHashMap<String, String>();
			if (result != null) {
				for (int i = 0; i < result.size(); i++) {
					Vendor v = result.get(i);
					vendorMap.put(v.getVendorCode(), v.getVendorName());
					if (i == 0) {
						vendorItem.setValue(v.getVendorCode());
					}
				}
				vendorItem.setValueMap(vendorMap);
			}
		}

	}

	private class OrgCodeEditorExitHandler implements EditorExitHandler {

		@Override
		public void onEditorExit(EditorExitEvent event) {
			int col = listGrid.getEditCol();
			int row = listGrid.getEditRow();

			if (col == 1) {
				Object obj = listGrid.getEditValue(row, col);
				if (obj == null) {
					obj = listGrid.getEditedCell(row, col);
				}
				Object orgCode = orgItem.getValue();
				if (obj != null && orgCode != null) {
					CommonService.Util.getInstance().getBasicVoByCodeAndOrgCode(obj.toString(), orgCode.toString(), new BasicAsyncCallback());
				}
			} else if (col > 8 && col < 16) {
				int amount = 0;
				for (int i = 9; i < 16; i++) {
					Object obj = listGrid.getEditValue(row, i);
					amount += Tools.toInteger(obj);
				}
				listGrid.setEditValue(row, 18, amount);
				Object amountObj = listGrid.getEditValue(row, 18);
				Object priceObj = listGrid.getEditValue(row, 17);
				Object jPriceObj = listGrid.getEditValue(row, 16);
				if (amountObj != null && priceObj != null && jPriceObj != null) {
					BigDecimal jp = new BigDecimal(jPriceObj.toString());
					BigDecimal pr = new BigDecimal(priceObj.toString());
					BigDecimal bd = new BigDecimal(amountObj.toString());
					jp = jp.multiply(bd);
					listGrid.setEditValue(row, 19, jp.toString());
					pr = pr.multiply(bd);
					listGrid.setEditValue(row, 20, jp.toString());
				}
			} else if (col == 17) {
				Object amountObj = listGrid.getEditValue(row, 18);
				Object priceObj = listGrid.getEditValue(row, 17);
				if (amountObj != null && priceObj != null) {
					BigDecimal bd = new BigDecimal(priceObj.toString());
					bd = bd.multiply(new BigDecimal(amountObj.toString()));
					listGrid.setEditValue(row, 19, bd.toString());
				}
			}
		}
	}

	private class BasicAsyncCallback implements AsyncCallback<BasicVo> {

		@Override
		public void onFailure(Throwable caught) {
			SC.say(caught.getMessage());
		}

		@Override
		public void onSuccess(BasicVo result) {
			if (result != null) {
				int row = listGrid.getEditRow();
				listGrid.setEditValue(row, 1, result.getPluCode());
				listGrid.setEditValue(row, 2, result.getBarCode());
				listGrid.setEditValue(row, 3, result.getPluName());
				listGrid.setEditValue(row, 4, result.getDepCode() + "-" + result.getDepName());
				listGrid.setEditValue(row, 5, result.getClsCode() + "-" + result.getClsName());
				listGrid.setEditValue(row, 6, result.getUnit());
				listGrid.setEditValue(row, 7, "无");
				listGrid.setEditValue(row, 8, "0");
				listGrid.setEditValue(row, 16, result.getjPrice().toString());
				listGrid.setEditValue(row, 17, result.getPrice().toString());
			} else {
				GoodsSearchWindow window = new GoodsSearchWindow(listGrid);
				window.centerInPage();
				window.setIsModal(true);
				window.setSize("500", "500");
				window.show();
			}
		}
	}

	private class OrgChangedHandler implements ChangedHandler {

		@Override
		public void onChanged(ChangedEvent event) {
			codeItem.setValue(orgItem.getValue());
			System.out.println(codeItem.getValue());
		}
	}

	private class ColorAsyncCallback implements AsyncCallback<LinkedHashMap<String, String>> {

		@Override
		public void onFailure(Throwable caught) {
			SC.say(caught.getMessage());
		}

		@Override
		public void onSuccess(LinkedHashMap<String, String> result) {
			if (result != null) {
				listGrid.setValueMap("color", result);
			}
		}
	}

	private class CupAsyncCallback implements AsyncCallback<LinkedHashMap<String, String>> {

		@Override
		public void onFailure(Throwable caught) {
			SC.say(caught.getMessage());
		}

		@Override
		public void onSuccess(LinkedHashMap<String, String> result) {
			if (result != null) {
				listGrid.setValueMap("cup", result);
			}
		}
	}
}
